package com.ruoyi.info.userController;

import com.cyl.h5.config.SecurityUtil;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.info.domain.FhInfoSigninlist;
import com.ruoyi.info.domain.FhInfoUser;
import com.ruoyi.info.domain.SignInDto;
import com.ruoyi.info.domain.SignInVo;
import com.ruoyi.info.service.IFhInfoSigninlistService;
import com.ruoyi.info.service.IFhInfoUserService;
import com.ruoyi.info.utils.PointsUtil;
import com.ruoyi.tokenTools.UserLoginToken;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.YearMonth;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 签到列表Controller
 *
 * @author ruoyi
 * @date 2024-11-09
 */
@Api(tags = "用户签到列表")
@RestController
@RequestMapping("/app/info/signinlist")
public class UserFhInfoSigninlistController extends BaseController
{
    @Autowired
    private IFhInfoSigninlistService fhInfoSigninlistService;

    @Autowired
    private IFhInfoUserService iFhInfoUserService;

    @Autowired
    private PointsUtil pointsUtil;


    /**
     * 今日签到
     */

    @UserLoginToken
    @ApiOperation("今日签到")
    @Log(title = "今日签到", businessType = BusinessType.UPDATE)
    @PutMapping("/toadysign")
    public R<String> todaySign( )
    {
        try{
            Date singinDate = new Date();
            //获取用户信息，修改积分
            FhInfoUser fhInfoUser = new FhInfoUser();
            Long userId = SecurityUtil.getLocalUserInfo().getId();
            fhInfoUser.setUserId(userId);
            List<FhInfoUser> fhInfoUsers = iFhInfoUserService.selectFhInfoUserList(fhInfoUser);
            FhInfoUser infoUser = fhInfoUsers.get(0);
            Long points = fhInfoUsers.get(0).getPoints();
            //比对这次和上次签到的日期是否相邻，相邻的话连续签到日期加一
            //查询上次的签到日期，和连续签到天数
            FhInfoSigninlist fhInfoSigninlist = new FhInfoSigninlist();
            fhInfoSigninlist.setUserId(userId);
            List<FhInfoSigninlist> fhInfoSigninlists = fhInfoSigninlistService.selectFhInfoSigninlistList(fhInfoSigninlist);
            //第一次时，没有数据的，得新增
            if(fhInfoSigninlists.isEmpty()){
                // 设置初始签到天数为 1
                FhInfoSigninlist newSigninlist = new FhInfoSigninlist();
                newSigninlist.setUserId(userId);
                newSigninlist.setSinginDate(singinDate);  // 当前时间作为签到时间
                newSigninlist.setSinginDay(1L);          // 初始签到天数为 1

                // 插入新的签到记录
                fhInfoSigninlistService.insertFhInfoSigninlist(newSigninlist);
                // 使用工具类增加积分并记录流水
                pointsUtil.addPoints(userId, 10L, "signin", null, "首次签到获得积分：10");

                return R.ok("首次签到成功");
            }
            //判断用户是否连续签到
            FhInfoSigninlist fhInfoSigninlist1 = fhInfoSigninlists.get(0);
            Calendar aCalendar = Calendar.getInstance();
            aCalendar.setTime(fhInfoSigninlist1.getSinginDate());
            int day1 = aCalendar.get(Calendar.DAY_OF_YEAR);
            aCalendar.setTime(singinDate);
            int day2 = aCalendar.get(Calendar.DAY_OF_YEAR);
            //判断今日是否签到
            if (day1 == day2) {
                return R.ok("今日已签到");
            }
            //连续签到
            if ((day2 - day1) == 1) {
                Long addPoints;
                if (fhInfoSigninlist1.getSinginDay() % 3 == 0) {
                    addPoints = 30L;
                } else {
                    addPoints = 10L;
                }
                Long singinDay = fhInfoSigninlist1.getSinginDay();
                singinDay += 1;
                //使用工具类增加积分并记录流水
                pointsUtil.addPoints(userId, addPoints, "signin", null, 
                    "连续签到第" + singinDay + "天，获得积分：" + addPoints);
                //修改签到表
                fhInfoSigninlist1.setSinginDay(singinDay);
                fhInfoSigninlist1.setSinginDate(singinDate);
                fhInfoSigninlistService.updateFhInfoSigninlist(fhInfoSigninlist1);
                return R.ok("签到成功");
            }

            //没有连续签到,积分加10，连续签到日设置为1
            //使用工具类增加积分并记录流水
            pointsUtil.addPoints(userId, 10L, "signin", null, "签到获得积分：10");
            //修改签到表
            fhInfoSigninlist1.setSinginDay(1L);
            fhInfoSigninlist1.setSinginDate(singinDate);
            fhInfoSigninlistService.updateFhInfoSigninlist(fhInfoSigninlist1);
            return R.ok("签到成功");
        }catch (Exception e){
            return R.fail(e.getMessage());
        }

    }

    /**
     * 查询签到列表列表
     */
    @UserLoginToken
    @ApiOperation("查询签到列表列表")
    @GetMapping("/list")
    public R<SignInDto>  list()
    {
        try{
            SignInDto signInDto = new SignInDto();
            Long integral = 10L;
            List<SignInVo> list = new ArrayList<>(7);

            FhInfoSigninlist fhInfoSigninlist = new FhInfoSigninlist();
            fhInfoSigninlist.setUserId(SecurityUtil.getLocalUserInfo().getId());
            List<FhInfoSigninlist> FhInfoSigninlist = fhInfoSigninlistService.selectFhInfoSigninlistList(fhInfoSigninlist);
            if(FhInfoSigninlist.isEmpty()){
                // 不插入数据库记录，仅构造前端返回数据
                signInDto.setUserSignInNum(0L);
                for (int i = 0; i < 8; i++) {
                    int multiple = (i % 3 == 0) ? 3 : 1;
                    list.add(new SignInVo(i, 0, 10L, multiple));
                }
                signInDto.setSignInVoList(list);
                return R.ok(signInDto);
            }else {
                // 签过到
                Long continueDay = FhInfoSigninlist.get(0).getSinginDay();
                int continueDays = continueDay.intValue();
                signInDto.setUserSignInNum(continueDay);
                // 1, 前六天的 flag是要固定的
                if (continueDays <= 6) {
                    for (int i = 1; i < 8; i++) {
                        int multiple = 1;
                        if(i%3==0){
                            multiple = 3;
                        }else {
                            multiple = 1;
                        }
                        if (i <= continueDays) {
                            list.add(new SignInVo(i, 1,integral,multiple));
                        } else {
                            list.add(new SignInVo(i, 0,integral,multiple));
                        }
                    }
                } else {
                    // 2, 6天后的签到天数要跟随日期增加
                    for (int i = 5; i > -2; i--) {
                        int multiple = 1;
                        if((continueDays - i)%3==0){
                            multiple = 3;
                        }else {
                            multiple = 1;
                        }
                        if (i > -1) {
                            list.add(new SignInVo(continueDays - i, 1,integral,multiple));
                        } else {
                            list.add(new SignInVo(continueDays + 1, 0,integral,multiple));
                        }
                    }
                }
            }
            signInDto.setSignInVoList(list);
            return R.ok(signInDto);
        }catch (Exception e){
            return R.fail(e.getMessage());
        }
    }

    /**
     * 查询当前月已签到列表
     */
    @UserLoginToken
    @ApiOperation("查询当前月已签到列表")
    @GetMapping("/currentMonthSigninList")
    public R<List<FhInfoSigninlist>> currentMonthSigninList() {
        try {
            Long userId = SecurityUtil.getLocalUserInfo().getId();

            // 获取当前月份的第一天和最后一天
            YearMonth currentYearMonth = YearMonth.now();
            LocalDate firstDay = currentYearMonth.atDay(1);
            LocalDate lastDay = currentYearMonth.atEndOfMonth();

            // 构造查询参数
            Map<String, Object> params = new HashMap<>();
            params.put("userId", userId);
            params.put("startTime", LocalDateTime.of(firstDay, LocalTime.MIN));
            params.put("endTime", LocalDateTime.of(lastDay, LocalTime.MAX));

            // 直接查询当月签到记录
            List<FhInfoSigninlist> signinLists = fhInfoSigninlistService.selectFhInfoSigninlistByMonth(params);

//            List<Integer> signedDays = new ArrayList<>();
//
//            // 提取签到日期（每月的第几天）
//            for (FhInfoSigninlist signin : signinLists) {
//                LocalDateTime signinDate = signin.getSinginDate().toInstant()
//                    .atZone(java.time.ZoneId.systemDefault())
//                    .toLocalDateTime();
//                int dayOfMonth = signinDate.getDayOfMonth();
//                signedDays.add(dayOfMonth);
//            }
//
            return R.ok(signinLists);
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }
}
